package com.sunyzc.ebaotech.simulator;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class HttpUtil {
	private static final int BUFFER_SIZE = 16 * 1024;
	private static final String DEFAULT_ENCODING = "UTF-8";

	public static void main(String[] args) throws Exception {
		System.out.println(httpRequest("https://github.com/", "GET", null, DEFAULT_ENCODING));
		String urlStr = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
		urlStr = urlStr.replace("ACCESS_TOKEN", "KO3UUTAd66s0mm-4_lh_WSusALj0BHOPD5v3csoQ4Qjqu1A2VxTsfbu3GNmnlnf-asdR58LtnQkgGvwSRmByjcFDnMDv4cHx-R9Po9n24a0");
		urlStr = urlStr.replace("TYPE", "image");
		System.out.println(uploadFile(urlStr, "1.png", new FileInputStream(new File("C:/1.png")), DEFAULT_ENCODING));
	}

	public static String httpRequest(String urlStr, String requestMethod, String requestData, String transEncoding) throws Exception {
		String responseData = null;
		HttpURLConnection urlConnection = null;
		OutputStream outputStream = null;
		BufferedReader bufferedReader = null;
		URL url = new URL(urlStr);
		try {
			urlConnection = (HttpURLConnection) url.openConnection();
			if ("https".equals(url.getProtocol())) {
				// 创建SSLContext对象，并使用我们指定的信任管理器初始化
				TrustManager[] trustManagers = { new TrustAnyTrustManager() };
				SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
				sslContext.init(null, trustManagers, new SecureRandom());
				SSLSocketFactory socketFactory = sslContext.getSocketFactory();
				HttpsURLConnection httpsURLConnection = (HttpsURLConnection) urlConnection;
				httpsURLConnection.setSSLSocketFactory(socketFactory);
				httpsURLConnection.setHostnameVerifier(new TrustAnyHostnameVerifier());
			}
			// 设置请求方式(GET/POST/HEAD/OPTIONS/PUT/DELETE/TRACE)
			urlConnection.setRequestMethod(requestMethod == null ? "" : requestMethod.toUpperCase());
			urlConnection.setUseCaches(false);
			urlConnection.setDoInput(true); // 为true时可以从URLConnection写请求数据，默认为true
			// 当有数据需要提交时
			if (requestData != null && !"".equals(requestData)) {
				urlConnection.setDoOutput(true); // 为true时可以向URLConnection写请求数据，默认为false
				outputStream = urlConnection.getOutputStream();
				outputStream.write(requestData.getBytes(transEncoding)); // 注意编码格式，防止中文乱码
				outputStream.flush();
			}
			bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), transEncoding));
			responseData = getStrFromReader(bufferedReader);
		} finally {
			IOUtil.closeQuietly(outputStream);
			IOUtil.closeQuietly(bufferedReader);
			if (urlConnection != null)
				urlConnection.disconnect();
		}
		return responseData;
	}

	public static String uploadFile(String urlStr, String fileName, InputStream inputStream, String transEncoding) throws Exception {
		String responseData = null;
		HttpURLConnection urlConnection = null;
		OutputStream outputStream = null;
		BufferedReader bufferedReader = null;
		URL url = new URL(urlStr);
		try {
			urlConnection = (HttpURLConnection) new URL(urlStr).openConnection();
			if ("https".equals(url.getProtocol())) {
				// 创建SSLContext对象，并使用我们指定的信任管理器初始化
				TrustManager[] trustManagers = { new TrustAnyTrustManager() };
				SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
				sslContext.init(null, trustManagers, new SecureRandom());
				SSLSocketFactory socketFactory = sslContext.getSocketFactory();
				HttpsURLConnection httpsURLConnection = (HttpsURLConnection) urlConnection;
				httpsURLConnection.setSSLSocketFactory(socketFactory);
				httpsURLConnection.setHostnameVerifier(new TrustAnyHostnameVerifier());
			}
			urlConnection.setRequestMethod("POST"); // 以POST方式提交表单
			urlConnection.setUseCaches(false); // POST方式不能使用缓存
			urlConnection.setDoInput(true); // 为true时可以从URLConnection写请求数据，默认为true

			// 设置请求头信息
			urlConnection.setRequestProperty("Connection", "Keep-Alive");
			urlConnection.setRequestProperty("Charset", transEncoding);
			// 设置边界
			String BOUNDARY = "----------" + System.currentTimeMillis();
			urlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
			// 请求正文信息
			StringBuffer headBuffer = new StringBuffer();
			headBuffer.append("--"); // 必须多两道线
			headBuffer.append(BOUNDARY);
			headBuffer.append("\r\n");
			headBuffer.append("Content-Disposition: filename=\"" + fileName + "\"\r\n");
			headBuffer.append("Content-Type:application/octet-stream\r\n\r\n");

			urlConnection.setDoOutput(true); // 为true时可以向URLConnection写请求数据，默认为false
			outputStream = urlConnection.getOutputStream();
			outputStream.write(headBuffer.toString().getBytes(transEncoding));// 获得输出流

			int length = 0;
			byte[] buffer = new byte[BUFFER_SIZE];
			while ((length = inputStream.read(buffer)) != -1)
				outputStream.write(buffer, 0, length);
			// 结尾部分
			byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes(transEncoding); // 定义最后数据分隔线
			outputStream.write(foot);
			outputStream.flush();
			bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), transEncoding));
			responseData = getStrFromReader(bufferedReader);
		} finally {
			IOUtil.closeQuietly(outputStream);
			IOUtil.closeQuietly(bufferedReader);
			if (urlConnection != null)
				urlConnection.disconnect();
		}
		return responseData;
	}

	private static String getStrFromReader(BufferedReader bufferedReader) throws IOException {
		StringBuffer responseData = new StringBuffer();
		// String line = null;
		// while ((line = bufferedReader.readLine()) != null)
		// responseData.append(line).append(System.getProperty("line.separator"));
		char[] buffer = new char[BUFFER_SIZE];
		int length = 0;
		while ((length = bufferedReader.read(buffer)) != -1)
			responseData.append(buffer, 0, length);
		return responseData.toString();
	}

	private static class TrustAnyTrustManager implements X509TrustManager {
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
		}

		public X509Certificate[] getAcceptedIssuers() {
			return new X509Certificate[] {};
		}
	}

	private static class TrustAnyHostnameVerifier implements HostnameVerifier {
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	}
}
